﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Telerik.WinControls;
using System.Linq;
using System.Net;
using System.IO;
using Telerik.WinControls.UI;
using TrendingReader.Classes;
using CSharpVerbalExpressions;
using HtmlAgilityPack;
using System.Threading.Tasks;
using System.Threading;

namespace TrendingReader.V2
{
    public partial class FrmReader : Telerik.WinControls.UI.RadForm
    {
        private TrendingReaderEntities _entities;
        //private FrmLoading frmLoading = new FrmLoading();

        public FrmReader()
        {
            this._entities = new TrendingReaderEntities();
            InitializeComponent();
        }

        private async void FrmReader_Load(object sender, EventArgs e)
        {
            //var markedStoryId = SettingFunctions.GetValue(_entities, "MarkedStoryId");
            //var markedChapterId = SettingFunctions.GetValue(_entities, "MarkedChapterId");
            ShowLoading();
            await LoadStoriesAsync();
            //if (!string.IsNullOrEmpty(markedStoryId) && TvStoriesList.Nodes.Count>0)
            //{
            //    TvStoriesList.SelectedNode.Value = markedStoryId;
            //    var storyId = new Guid(TvStoriesList.SelectedNode.Value.ToString());
            //    await LoadChapters(storyId);
            //    if (!string.IsNullOrEmpty(markedChapterId) && TvChaptersList.Nodes.Count > 0)
            //    {
            //        TvChaptersList.SelectedNode.Value = markedChapterId;
            //        var chapterId = new Guid(TvChaptersList.SelectedNode.Value.ToString());
            //        await GetItemsForeachChapter(chapterId);
            //    }
            //}
            HideLoading();
        }

        private async void TvStoriesList_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            ShowLoading();
            var storyId = new Guid(TvStoriesList.SelectedNode.Value.ToString());
            await LoadChaptersAsync(storyId);
            HideLoading();
        }

        private async void TvChaptersList_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            ShowLoading();

            var chapterId = new Guid(TvChaptersList.SelectedNode.Value.ToString());

            var strImages = await GetItemsForeachChapterAsync(chapterId);

            WbsImagesList.Invoke((MethodInvoker)(() => WbsImagesList.DocumentText = "<html><body>" + strImages + "</body></html>"));
            WbsImagesList.Invoke((MethodInvoker)(() => WbsImagesList.Focus()));
        }

        private async Task LoadStoriesAsync()
        {
            TvStoriesList.Invoke((MethodInvoker)(() => TvStoriesList.Nodes.Clear()));
            await Task.Run(() =>
            {
                //var list = this._entities.Stories.OrderBy(s => s.Name).ToList();

                var list = (from stories in this._entities.Stories
                            orderby stories.UpdateDate descending 
                            select new { Id = stories.Id, Name = stories.Name }).ToList();

                TvStoriesList.Invoke((MethodInvoker)(() => TvStoriesList.DataSource = list));
                //var orderIndex = 0;
                //foreach (var item in list)
                //{
                //    orderIndex++;
                //    TvStoriesList.Invoke((MethodInvoker)(() => TvStoriesList.Nodes.Add(new RadTreeNode { Text = string.Format("{0}. {1}", orderIndex, item.Name), Value = item.Id.ToString() })));
                //}
            });
        }

        private async Task LoadChaptersAsync(Guid storyId)
        {
            await Task.Run(() =>
            {
                TvChaptersList.Invoke((MethodInvoker)(() => TvChaptersList.Nodes.Clear()));

                var list = (from chapters in this._entities.Chapters
                            where chapters.StoryId == storyId
                            orderby chapters.OrderIndex descending
                            select new { Id = chapters.Id, Name = chapters.OrderIndex + ". " + chapters.Name }).ToList();

                TvChaptersList.Invoke((MethodInvoker)(() => TvChaptersList.DataSource = list));                
                TvChaptersList.Invoke((MethodInvoker)(() => TvChaptersList.Focus()));
            });
        }

        private async Task<string> GetItemsForeachChapterAsync(Guid chapterId)
        {
            try
            {
                var strImages = string.Empty;

                await Task.Run(() =>
                {
                    var chapter = _entities.Chapters.FirstOrDefault(c => c.Id == chapterId);

                    if (chapter == null)
                    {
                        strImages = "<p style='color: red;font-size: 17px; display: block; text-align: center;'>We don't have content for this chapter.</p>";
                        return;
                    }

                    var web = new HtmlWeb();
                    HtmlAgilityPack.HtmlDocument doc;

                    if (string.IsNullOrEmpty(chapter.Link))
                    {
                        strImages = "<p style='color: red;font-size: 17px; display: block; text-align: center;'>We don't have content for this chapter.</p>";
                        return;
                    }

                    // get link
                    doc = web.Load(chapter.Link);

                    if (doc == null)
                    {
                        strImages = "<p style='color: red;font-size: 17px; display: block; text-align: center;'>We don't have content for this chapter.</p>";
                        return;
                    }

                    var htmlText = doc.DocumentNode.InnerHtml;

                    var isGoogleLink = true;
                    var strLinks = string.Empty;
                    string[] linksList = { };

                    var verbEx = new VerbalExpressions()
                        .Then("var slides_page_url_path = [")
                        .Anything()
                        .Then("];");

                    strLinks = verbEx.Capture(htmlText, "2");

                    if (string.IsNullOrEmpty(strLinks))
                    {
                        verbEx = new VerbalExpressions()
                        .Then("var slides_page_path = [")
                        .Anything()
                        .Then("];");
                        isGoogleLink = false;
                        strLinks = verbEx.Capture(htmlText, "2");
                    }

                    if (string.IsNullOrEmpty(strLinks))
                    {
                        strImages = "<p style='color: red;font-size: 17px; display: block; text-align: center;'>We don't have content for this chapter.</p>";
                        return;
                    }

                    if (strLinks.Contains(","))
                    {
                        linksList = strLinks.Split(',');
                    }
                    else if (strLinks.Contains("|"))
                    {
                        linksList = strLinks.Split('|');
                    }

                    var itemsList = new List<string>();
                    foreach (var link in linksList)
                    {
                        itemsList.Add(link.Trim().Replace("\"", ""));
                    }

                    if (itemsList.Count > 0)
                    {
                        if (!isGoogleLink)
                            itemsList.Sort();

                        foreach (var item in itemsList)
                        {
                            strImages += "<img src='" + item + "' width='100%' /><br/>";
                        }
                    }
                    else
                    {
                        strImages = "<p style='color: red;font-size: 17px; display: block; text-align: center;'>We don't have content for this chapter.</p>";
                        return;
                    }
                });

                return strImages;

            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private void FrmReader_FormClosing(object sender, FormClosingEventArgs e)
        {
            //if (TvStoriesList.SelectedNode != null)
            //    await SettingFunctions.SetValue(_entities, "SID", TvStoriesList.SelectedNode.Value.ToString());
            //if (TvChaptersList.SelectedNode != null)
            //    await SettingFunctions.SetValue(_entities, "CID", TvChaptersList.SelectedNode.Value.ToString());

            if (RadMessageBox.Show("Are you sure you want to close?", "Hey!", MessageBoxButtons.YesNo, RadMessageIcon.Question)
                == System.Windows.Forms.DialogResult.Yes)
            {
                _entities = null;
                //frmLoading.Dispose();
                this.Dispose();
            }
            else
            {
                e.Cancel = true;
            }

        }

        private void WbsImagesList_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            if (this.WbsImagesList.ReadyState == WebBrowserReadyState.Complete)
            {
                HideLoading();
            }
        }

        private void ShowLoading()
        {
            //if (frmLoading != null && !frmLoading.Visible)
            //    frmLoading.Show();
            WbpLoading.Visibility = ElementVisibility.Visible;
            WbpLoading.StartWaiting();
        }

        private void HideLoading()
        {
            //if (frmLoading != null && frmLoading.Visible)
            //    frmLoading.Hide();
            WbpLoading.StopWaiting();
            WbpLoading.Visibility = ElementVisibility.Hidden;
        }
    }
}
